package net.xconcepts.stockdata.model.analysis.indicator;

import java.util.HashMap;
import java.util.Map;

import net.xconcepts.stockdata.model.analysis.symbol.Symbol;
import net.xconcepts.stockdata.model.tick.SymbolTick;

/**
 * 
 * @author Steven
 *
 * @param <T> The type of the result from the indicator
 * @param <K> The type of the input data
 */
public abstract class Indicator<T, K> {
	
	private Indicator<K, ?> mBaseIndicators = null;
	
	public Indicator () {
		
	}
	
	public Indicator (Indicator<K, ?> baseIndicator) {
		mBaseIndicators = baseIndicator;
	}
	
	/** Indicator behavior is undefined if no
	 * ticks have been process, usually null*/
	public final Map<Symbol, T> processTicks(Map<Symbol, SymbolTick> ticks) {
		
		Map<Symbol, T> results = new HashMap<Symbol, T>();
		
		if(mBaseIndicators != null) {
			Map<Symbol, K> baseIndicatorResults = mBaseIndicators.processTicks(ticks);
			for(SymbolTick tick : ticks.values()) {			
				results.put(tick.getSymbol(), 
						processSymbolTick(tick, baseIndicatorResults.get(tick.getSymbol())));
			}
		} else {
			for(SymbolTick tick : ticks.values()) {			
				results.put(tick.getSymbol(), 
						processSymbolTick(tick, null));
			}
		}
				
		return results;
	}
	
	
	/**
	 * 
	 * @param tick
	 * @param baseIndicatorResult null if no base indicator
	 * @return
	 */
	protected abstract T processSymbolTick(SymbolTick tick, K baseIndicatorResult);

}
